#include"Camerak.h"

Camerak::Camerak(void)
{
	movement_rate = 0.15f;
	rotation_rate = float(m3dDegToRad(1.0f));
	cameraFrame.SetOrigin(0,2,0);
	camera_mode = THIRD_PERSON;
}

Camerak::~Camerak(void)
{
}

// This function alows the camera to move along the worlds z axis regardless of the cameras own orientation
void Camerak::moveForward()
{
	M3DVector3f temp;
	cameraFrame.GetForwardVector(temp);
	float x = cameraFrame.GetOriginX() + (temp[0] * movement_rate);
	float y = cameraFrame.GetOriginY();
	float z = cameraFrame.GetOriginZ() + (temp[2] * movement_rate);
	cameraFrame.SetOrigin(x,y,z);
}

// This function alows the camera to move along the worlds z axis regardless of the cameras own orientation
void Camerak::moveBackward()
{
	M3DVector3f temp;
	cameraFrame.GetForwardVector(temp);
	float x = cameraFrame.GetOriginX() + (temp[0] * -movement_rate);
	float y = cameraFrame.GetOriginY();
	float z = cameraFrame.GetOriginZ() + (temp[2] * -movement_rate);
	cameraFrame.SetOrigin(x,y,z);
}


// The following two functions are used to differentiate camera behaviour between objects that will remain stationary to the camera like a skybox,
// or that will move independantly of the camera like actors or scene objects
void Camerak::setCameraStatic(GLMatrixStack* imatrix)
{
	cameraFrame.GetCameraMatrix(mCamera, true);
	imatrix->LoadMatrix(mCamera);
}

void Camerak::setCameraPushMatrix(GLMatrixStack* imatrix)
{
	cameraFrame.GetCameraMatrix(mCamera);
	imatrix->PushMatrix(mCamera);
}


// This function is used to switch between the camera modes and realign the camera in relation to each mode.
void Camerak::setCameraMode(int imode, Vector3f iorigin, float iorientation)  // the iorigin is the players origin, and the iorientation is the players angle from the forward vector
{
	if(imode > 3 && imode < -1)   // This is to avoid errors if a non defined value is sent to the function
	{
		camera_mode = imode;
	}
	if(camera_mode == FIRST_PERSON)
	{
		resetUpVector();
	}
	if(camera_mode == THIRD_PERSON)
	{
		resetUpVector();
		rotateAntiClockWise(iorientation);
	}
	if(camera_mode == FREE_ROAMING)
	{
		resetUpVector();
	}
}

void Camerak::update(Vector3f iorigin, float iangle)
{
	if(camera_mode == FIRST_PERSON)
	{
		cameraFrame.SetOrigin(iorigin.x * 0.05f, (iorigin.y * 0.05f) + 0.75f, iorigin.z * 0.05f);	// The value 0.05 is decided by the scaleing factor applied to the player
	}																								//  md2 model when displaye, this is far from ideal
	if(camera_mode == THIRD_PERSON)
	{
		cameraFrame.SetOrigin(iorigin.x * 0.05f, (iorigin.y * 0.05f) + 0.75f, iorigin.z * 0.05f);
		cameraFrame.TranslateLocal(0,0,-6);
	}
}